package com.transcargo.action;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.StringTokenizer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.transcargo.errors.ErrorList;
import com.transcargo.data.Cache;
import com.transcargo.db.db;
import com.transcargo.db.dbException;
import com.transcargo.geo.GeoObjectNotFoundException;
import com.transcargo.users.Contact;
import com.transcargo.users.User;
import com.transcargo.users.UserNotFoundException;
import com.transcargo.util.Checker;
import com.transcargo.util.Normalizer;

public class EditPostCargoAction extends AuthAction {
	private String datetype = "";
	private String date_from = "";
	private String date_to = "";
	private String from = "";
	private String regFrom = "";
	private String to = "";
	private String regTo = "";
	private String owntransport = "";
	private String cargo_type = "";
	private String volume = "";
	private String weight = "";
	private String tir = "";
	private String adr = "";
	private String payment_type = "";
	private String bid = "";
	private String payment_curr = "";
	private String urgent = "";
	private String urgent_time = "";
	private String passing = "";
	private String comments = "";
	private String contact = "";
	private String loading="";
	private String cargo = "";
	private String customs = "";
	private String cars = "";
	private String combined = "";
	private String times = "";
	private int cid_from = 0;
	private int rid_from = 0;
	private int ctid_from = 0;
	private int cid_to = 0;
	private int rid_to = 0;
	private int ctid_to = 0;
	private int Id = 0;
	
	private void servletGetValues(HttpServletRequest request) throws ServletParametersException {
		datetype = request.getParameter("datetype");
		date_from = request.getParameter("date_from");
		date_to = request.getParameter("date_to");
		from = request.getParameter("from");
		regFrom = request.getParameter("regfrom");
		to = request.getParameter("to");
		regTo = request.getParameter("regto");
		owntransport = request.getParameter("owntransport");
		cargo_type = request.getParameter("cargo_type");
		volume = request.getParameter("volume");
		weight = request.getParameter("weight");
		tir = request.getParameter("tir");
		adr = request.getParameter("adr");
		payment_type = request.getParameter("payment_type");
		bid = request.getParameter("bid");
		payment_curr = request.getParameter("payment_curr");
		urgent = request.getParameter("urgent");
		urgent_time = request.getParameter("urgenttime");
		passing = request.getParameter("passing");
		comments = request.getParameter("comments");
		contact = request.getParameter("contact");
		cargo = request.getParameter("cargo");
		customs = request.getParameter("customs");
		cars = request.getParameter("cars");
		combined = request.getParameter("combined");
		times = request.getParameter("times");
		String id = request.getParameter("id");
		if (id == null || id.length() == 0) throw new ServletParametersException();
		Id = Integer.parseInt(id);
		
		if (from == null) from="";
		if (regFrom == null) regFrom="";
		if (to == null) to="";
		if (regTo == null) regTo="";
		if (to == null) to="";
		if (owntransport == null) owntransport="";
		if (tir == null) tir="";
		if (bid == null) bid="";
		if (volume == null) volume="";
		if (weight == null) weight="";
		if (urgent == null) urgent="";
		if (passing == null) passing="";
		if (comments == null) comments="";
		if (cargo == null) cargo="";
		if (customs == null) customs="";
		if (cars == null) cars="1";
		if (combined == null) combined="";
		if (times == null) times="5";
        if (!urgent.equals("on") || urgent_time == null || urgent_time.length() == 0) urgent_time="0:00";
		
        Iterator<String> it = Cache.getTransportLoadings().keySet().iterator();
        while (it.hasNext()) {
            String key = it.next();
            String b = request.getParameter("load" + key);
            if (b != null && b.equals("on")) loading = loading.concat(loading.length() > 0 ? "," + key : key);
        }
        StringTokenizer tok1 = new StringTokenizer(regFrom,"-");
        StringTokenizer tok2 = new StringTokenizer(regTo,"-");
        try {
	        switch (tok1.countTokens()) {
	        	case 3:
	        		cid_from = Integer.parseInt(tok1.nextToken());
	        		rid_from = Integer.parseInt(tok1.nextToken());
	        		ctid_from = Integer.parseInt(tok1.nextToken());
	        		break;
	        	case 2:
	        		cid_from = Integer.parseInt(tok1.nextToken());
	        		rid_from = Integer.parseInt(tok1.nextToken());
	        		break;
	        	case 1:
	        		cid_from = Integer.parseInt(tok1.nextToken());
	        		break;
	        }
	        switch (tok2.countTokens()) {
	        	case 3:
	        		cid_to = Integer.parseInt(tok2.nextToken());
	        		rid_to = Integer.parseInt(tok2.nextToken());
	        		ctid_to = Integer.parseInt(tok2.nextToken());
	        		break;
	        	case 2:
	        		cid_to = Integer.parseInt(tok2.nextToken());
	        		rid_to = Integer.parseInt(tok2.nextToken());
	        		break;
	        	case 1:
	        		cid_to = Integer.parseInt(tok2.nextToken());
	        		break;
	        }
        } catch (NumberFormatException e) {
        	System.out.println("WARNING!! Invalid number in regions: " + e.getMessage());
        }
    }
    private void servletValidateValues() throws ServletValidationException, ServletActionException {
    	User user = null;
    	try {
			user = new User(User_Id, dbase);
	    	if (contact != null && contact.length() > 0) {
	    		int contact_id = Integer.parseInt(contact);
	    		if (contact_id > 0) {
	    			Contact c = user.getContact(contact_id);
	    			if (c == null) {
	    				throw new ServletValidationException("Invalid contact value");
	    			}
	    		}
	    	}
			list = dbase.execute("SELECT count(id) FROM posted_cargo WHERE id=" + Integer.toString(Id) + " AND (user_id mod 100000000)=" + Integer.toString(User_Id));
			if (list != null) {
				iter = list.iterator();
	            String[] str = iter.next();
	            if (str[0].equals("0")) throw new ServletValidationException("Invalid post id");
			} else throw new ServletValidationException("Invalid post id");
    	}  catch (dbException e) {
			System.out.println("Db exception: " + e.getMessage());
			throw new ServletActionException();
		} catch (GeoObjectNotFoundException e) {
			System.out.println("Geo Object not found: " + e.getMessage());
			throw new ServletActionException();
		} catch (UserNotFoundException e) {
			System.out.println("User not found: " + e.getMessage());
			throw new ServletActionException();
		}
        try {
	        if (weight.length() > 0) {
	        	weight = weight.replace(",", ".");
	        	if (Float.parseFloat(weight) == 0) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_WEIGHT);
	        }
        
        } catch (NumberFormatException e) {
        	throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_WEIGHT);
        }
        try {
	        if (times.length() > 0) {
	        	Integer.parseInt(times);
	        }
        
        } catch (NumberFormatException e) {
        	times = "1";
        }
        try {
	        if (cars.length() > 0) {
	        	Integer.parseInt(cars);
	        }
        
        } catch (NumberFormatException e) {
        	throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CARSNUMBER);
        }
        try {
	        if (volume.length() > 0) {
	        	volume = volume.replace(",", ".");
	        	if (Integer.parseInt(volume) == 0) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CVOLUME);
	        }
        
        } catch (NumberFormatException e) {
        	throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CVOLUME);
        }
        try {
	        if (bid.length() > 0) {
	        	bid = bid.replace(",", ".");
	        	if (Float.parseFloat(bid) == 0) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_BID);
	        }
        
        } catch (NumberFormatException e) {
        	throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_BID);
        }
        if (cargo.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_CARGONAME_MISSING);
        if (cargo.length() >255) throw new ServletValidationException(ErrorList.ERROR_STR_CARGONAME_TOO_LONG);
        if (cargo_type.length() == 0 || Integer.parseInt(cargo_type) == 0 || Integer.parseInt(cargo_type) > 255) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CARGO);
        if (loading.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_LOADING_MISSING);
        if (volume.length() == 0 || Integer.parseInt(volume) == 0) throw new ServletValidationException(ErrorList.ERROR_STR_CVOLUME_MISSING);
        if (weight.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_WEIGHT_MISSING);
        if (Integer.parseInt(volume) > 200) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CVOLUME);
        if (Integer.parseInt(weight) > 200) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_WEIGHT);
        if (cars.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_CARSNUMBER_MISSING);
        if (Integer.parseInt(cars) == 0 || Integer.parseInt(cars) > 100) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_CARSNUMBER);
        if (adr.length() > 0 && (Integer.parseInt(adr) == 0 || Integer.parseInt(adr) > 9)) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_ADR);
        if (date_from == null || date_from.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_DATELOAD_MISSING);
        if (date_to == null || date_to.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_DATELOAD_MISSING);
        if (!Checker.CheckDate(date_from)) throw new ServletValidationException(ErrorList.ERROR_STR_DATELOAD_INVALID);
        if (!Checker.CheckDate(date_to)) throw new ServletValidationException(ErrorList.ERROR_STR_DATELOAD_INVALID);
        if (from.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_CITYFROM_MISSING);
        if (cid_from == 0) throw new ServletValidationException(ErrorList.ERROR_STR_COUNTRYFROM_MISSING);
        if (from.length() > 255) throw new ServletValidationException(ErrorList.ERROR_STR_CITYFROM_TOO_LONG);
        if (to.length() > 255) throw new ServletValidationException(ErrorList.ERROR_STR_CITYTO_TOO_LONG);
        if (to.length() == 0) throw new ServletValidationException(ErrorList.ERROR_STR_CITYTO_MISSING);
        if (cid_to == 0) throw new ServletValidationException(ErrorList.ERROR_STR_COUNTRYTO_MISSING);
        if (bid.length() > 12) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_BID);
        if (Integer.parseInt(payment_type) > 255) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_PAYMENTTYPE);
        if (!payment_curr.equals("-") && (Integer.parseInt(payment_curr) == 0 || Integer.parseInt(payment_curr) > 255)) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_PAYMENTCURRENCY);
        if (urgent.equals("on") && !Checker.CheckTime(urgent_time)) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_URGENTTIME);
        if (comments.length() > 255) throw new ServletValidationException(ErrorList.ERROR_STR_COMMENTS_TOO_LONG);
        if (urgent.equals("on") && datetype.equals("off")) throw new ServletValidationException(ErrorList.ERROR_STR_URGENT_PERMANENT);
        if ((Integer.parseInt(times) == 0 || Integer.parseInt(times) > 7) && datetype.equals("off")) throw new ServletValidationException(ErrorList.ERROR_STR_INVALID_TIMES);
    }
    private void servletExecuteAction() throws ServletActionException {
    	try {
	        db.PreStatement pre = dbase.CreateStatement("UPDATE posted_cargo SET " +
	        		"date_load=?," +
	        		"date_unload=?," +
	        		"country_id_from=?," +
	        		"region_id_from=?," +
	        		"city_id_from=?," +
	        		"city_value_from=?," +
	        		"country_id_to=?," +
	        		"region_id_to=?," +
	        		"city_id_to=?," +
	        		"city_value_to=?," +
	        		"cargo=?," +
	        		"cars=?," +
	        		"type=?," +
	        		"loading=?," +
	        		"tir=?," +
	        		"adr=?," +
	        		"weight=?," +
	        		"volume=?," +
	        		"payment_bid=?," +
	        		"payment_type=?," +
	        		"payment_currency=?," +
	        		"urgent=?," +
	        		"urgent_time=?," +
	        		"combined=?," +
	        		"passing=?," +
	        		"customs=?," +
	        		"comments=?," +
	        		"permanent=?," + 
	        		"times=?, " +
	        		"user_id=?, " +
	        		"date_posted=CURRENT_TIMESTAMP " +
	        		"WHERE id="+Integer.toString(Id));
	        pre.Insert(Normalizer.NormalizeDate(date_from));
	        pre.Insert(Normalizer.NormalizeDate(date_to));
	        pre.Insert(cid_from);
	        pre.Insert(rid_from);
	        pre.Insert(ctid_from);
	        pre.Insert(from);
	        pre.Insert(cid_to);
	        pre.Insert(rid_to);
	        pre.Insert(ctid_to);
	        pre.Insert(to);
	        pre.Insert(cargo);
	        pre.Insert(cars);
	        pre.Insert(cargo_type);
	        pre.Insert(loading);
	        pre.Insert(tir.equals("on")?"1":"0");
	        pre.Insert(adr.length()>0?adr:"0");
	        pre.Insert(weight);
	        pre.Insert(volume);
	        pre.Insert(bid.length()>0?bid:"0");
	        pre.Insert(payment_type);
	        pre.Insert(payment_curr.equals("-")?"0":payment_curr);
	        pre.Insert(urgent.equals("on")?"1":"0");
	        pre.Insert(urgent_time);
	        pre.Insert(combined.equals("on")?"1":"0");
	        pre.Insert(passing.equals("on")?"1":"0");
	        pre.Insert(customs.equals("on")?"1":"0");
	        pre.Insert(comments);
	        pre.Insert(datetype.equals("off")?"1":"0");
	        pre.Insert(times);
	        pre.Insert((contact != null && contact.length() > 0)?(Integer.parseInt(contact) * 100000000 + User_Id):User_Id);
	        dbase.executeUpdate(pre);
    	} catch (SQLException e) {
			System.out.println("SQL exception: " + e.getMessage());
			throw new ServletActionException();
		} catch (dbException e) {
			System.out.println("Db exception: " + e.getMessage());
			throw new ServletActionException();
		}
    }

    public void processAction(HttpServletRequest request, HttpServletResponse response) throws ServletException {
		try {
            servletGetValues(request);
            servletValidateValues();
            servletExecuteAction();
            sendRedirect(response, "posts.jsp?i=2");
	    } catch (ServletParametersException e) {
            if (e.getMessage() != null) {
                sendError(response, new Exception(e.getMessage()));

            } else {
                sendRedirect(response, "posts.jsp");
            }
        }  catch (ServletValidationException e) {
            sendError(response, new Exception(e.getMessage()));
        }  catch (ServletActionException e) {
            sendError(response, new Exception("" + ErrorList.ERROR_STR_GENERIC));
        }
    }
}
